import dayjs from "dayjs";
import {BaseEle, createUUID, setBoolAttr} from "./core.js";

/**
 * @interface
 */
class ZfcInputInterface {
    static inputType = '';
    handleNewValue(v) {
        return v;
    }
    init () {};
    attrChanged() {};
}

class DatetimeLocal extends ZfcInputInterface{
    static inputType = 'datetime-local'
    _renderContent(ctx, value) {
        if (value) {
            let showValue = '';
            let ctx_format = ctx.getAttribute('show-format') ?? 'YYYY-MM-DD HH:mm:ss';
            // showValue = value.replace('Z', '').split('T').join(' ');
            showValue = dayjs(value).format(ctx_format);
            ctx._shadowRoot.querySelector('#content').textContent = showValue
        }
    }
    init(ctx) {
        let self = this;
        ctx._shadowRoot.innerHTML = `
                  <z-inputpopup class="popup" style="--my-anchor-min-width: 10em">
                    <div id="content" slot="selectcontent"></div>
                    <z-datetimelocal-picker class="input" ></z-datetimelocal-picker>
                </z-inputpopup>
             `;
        ctx._shadowRoot.querySelector(':scope .input').addEventListener('change', (e) => {
            ctx.value = e.target.value;
            console.log('zfcinput DatetimeLocal', ctx.value);
            self._renderContent(ctx, ctx.value);
            ctx.dispatchEvent(new Event('change'))
        });
        setBoolAttr(ctx._shadowRoot.querySelector(':scope .popup'), 'readonly', ctx.getAttribute('readonly'));
    }
    handleNewValue(newValue) {
        console.log('datetimeLocal handleNewValue', newValue);
        if (typeof newValue === 'undefined' || newValue === 'undefined') {
            return new Date();
        }
        return newValue
    }
    attrChanged(ctx, name, oldValue, newValue) {
        if (name ==='value') {
            console.log('zfcinput DatetimeLocal attrChanged value', name, newValue);
            this._renderContent(ctx, newValue)
        }
        else {
            setBoolAttr(ctx._shadowRoot.querySelector(':scope .popup'), name, newValue);
        }
    }
}

class CaSelectLocal extends ZfcInputInterface{
    static inputType = 'select'
    _renderselect(ctx, newValue) {
        let findedOption = ctx._shadowRoot.querySelector(':scope .input').getOptionFromValue(newValue)
        console.log('getContentFromValue', newValue, findedOption);
        if (findedOption) {
            ctx._shadowRoot.querySelector('#' + this.contentID).innerHTML = findedOption.innerHTML
        }
    }
    init(ctx) {
        let self = this;
        self.contentID = 'content_' + createUUID()
        let popupcls = ' ';
        let pos = ctx.getAttribute('pos');
        if (pos) {
            popupcls += ' pos-' + pos;
        }
        let optionUIS = [...ctx.childNodes].filter(v => {
            return v.nodeName === 'OPTION'
        }).map(v => v.cloneNode(true))
        // console.log('CaSelectLocal', ctx, popupcls)
        ctx._shadowRoot.innerHTML = `<z-inputpopup  class="popup ${popupcls}">
                    <div id="${self.contentID}"  slot="selectcontent">请选择</div>
                    <z-option-picker class="input" ></z-option-picker>
                </z-inputpopup>`;
        ctx._shadowRoot.querySelector(':scope .input').renderPicker(optionUIS)
        ctx._shadowRoot.querySelector(':scope .input').addEventListener('change', (e) => {
            ctx.value = e.target.value;
            // console.log('zfcinput select', ctx.value)
            self._renderselect(ctx, ctx.value);
            ctx.setLock()
            ctx.dispatchEvent(new Event('change'))
        })
        setBoolAttr(ctx._shadowRoot.querySelector(':scope .popup'), 'readonly', ctx.getAttribute('readonly'));
    }
    attrChanged(ctx, name, oldValue, newValue) {
        if (!this._locks) {
            requestAnimationFrame(() => {
                if (name ==='value') {
                    this._renderselect(ctx, newValue)
                }
                else {
                    setBoolAttr(ctx._shadowRoot.querySelector(':scope .popup'), name, newValue);
                }
            })
        }
    }
}

class BaseLocal extends ZfcInputInterface {
    init(ctx) {
        ctx._shadowRoot.innerHTML = `<label class="z-input-container"><input type="${ctx.type}" class="input" /></label>`;
        // ctx._shadowRoot.querySelector(':scope .input').addEventListener('change', (e) => {
        //     ctx.setLock()
        //     console.log('BaseLocal', e)
        //     ctx.value = e.target.value;
        // })
        Object.defineProperty(ctx, 'value', {
            get: function () {
                return ctx._shadowRoot.querySelector(':scope .input').value;
            },
            set: function (value) {
                if (!ctx._locks) {
                    console.log('BaseLocal set')
                    ctx._shadowRoot.querySelector(':scope .input').value = value;
                }
            },
            enumerable: true,
            configurable: true
        });
        this._initProps(ctx)
    }
    _initProps(ctx){
        setBoolAttr(ctx._shadowRoot.querySelector(':scope .input'), 'readonly',
            ctx.getAttribute('readonly'));
    }
}

class ZoolcoolColorPicker extends customElements.get('toolcool-color-picker') {
    connectedCallback() {
        super.connectedCallback();
        this.shadowRoot.querySelector('.color-picker').setAttribute('part', 'zoolcool_color_picker')
        this.shadowRoot.querySelector('button').setAttribute('part', 'zoolcool_color_picker_button')
    }
}

customElements.define('zoolcool-color-picker', ZoolcoolColorPicker);

class ColorLocal extends BaseLocal {
    static inputType = 'bcolor';
    init(ctx) {
        ctx._shadowRoot.innerHTML = `<label class="z-input-container"><zoolcool-color-picker class="input"></zoolcool-color-picker></label>`
        Object.defineProperty(ctx, 'value', {
            get: function () {
                return ctx._shadowRoot.querySelector(':scope .input').rgba;
            },
            set: function (value) {
                ctx._shadowRoot.querySelector(':scope .input').color = value;
            },
            enumerable: true,
            configurable: true
        });
        this._initProps(ctx)
    }
    attrChanged(ctx, name, oldValue, newValue) {
        if (name === 'value') {
            console.log('ColorLocal', ctx._shadowRoot.querySelector(':scope .input'), newValue);
            ctx._shadowRoot.querySelector(':scope .input').setAttribute('color', newValue)
        }
    }
}

class TextareaLocal extends BaseLocal {
    static inputType = 'textarea';
    init(ctx) {
        ctx._shadowRoot.innerHTML = `<label class="z-input-container"><textarea class="z-textarea input"></textarea></label>`
        Object.defineProperty(ctx, 'value', {
            get: function () {
                return ctx._shadowRoot.querySelector(':scope .input').textContent;
            },
            set: function (value) {
                ctx._shadowRoot.querySelector(':scope .input').textContent = value;
            },
            enumerable: true,
            configurable: true
        });
        this._initProps(ctx)
    }
    attrChanged(ctx, name, oldValue, newValue) {
        if (name === 'value') {
            ctx._shadowRoot.querySelector(':scope .input').textContent = newValue;
        }
    }
}

let supportTypes = {
    [ColorLocal.inputType]: ColorLocal,
    [TextareaLocal.inputType]: TextareaLocal,
    [CaSelectLocal.inputType]: CaSelectLocal,
    [DatetimeLocal.inputType]: DatetimeLocal,
}

class ZfcInput extends BaseEle {
    constructor() {
        super();
        // this.attachShadow({ mode: 'open' });
        this._shadowRoot = this;
        this.type = this.getAttribute('type') ?? 'text';
        /**
         *
         * @type {ZfcInputInterface}
         */
        this.comIns = new BaseLocal()
        if (supportTypes[this.type]) {
            this.comIns = new supportTypes[this.type]();
        }
        this.init()
    }
    init() {
         if (this.comIns?.init) {
             this.comIns.init(this)
         }
    }
    attrChanged(name, oldValue, newValue) {
        let cachenv = newValue
        if (name === 'value') {
            console.log('handleNewValue this.comIns', cachenv, this.comIns)
            if (this.comIns?.handleNewValue) {
                cachenv = this.comIns.handleNewValue(cachenv)
            }
            this._shadowRoot.querySelector(':scope .input').setAttribute('value', cachenv)
        }
        else {
            setBoolAttr(this._shadowRoot.querySelector(':scope .input'), name, cachenv)
        }
        if (this.comIns?.attrChanged) {
            this.comIns.attrChanged(this, name, oldValue, cachenv)
        }
    }
}

ZfcInput.defsel('z-fcinput', {
    attrs: {
        value: '',
        placeholder: '',
        readonly: false,
    }
})

class ZfcInputSet extends BaseEle {
    constructor() {
        super();
    }
    attrChanged(name, oldValue, newValue) {
        if (name === 'readonly') {
            this._log('ZfcInputSet readonly', newValue);

            [...this.querySelectorAll(':scope z-fcinput')].forEach(v => {
                setBoolAttr(v, 'readonly', newValue)
            })
        }
    }
}

ZfcInputSet.defsel('z-fcinput-set', {
    attrs: {
        readonly: false,
    }
})